﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using ThingyCloudWPF.Network.Messages;
using ThingyCloudWPF.Graphics;

namespace ThingyCloudWPF
{
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
		private List<ThingyGraphic> ThingyGraphics = new List<ThingyGraphic>();
		private List<AvatarGraphic> AvatarGraphics = new List<AvatarGraphic>();

		public MainWindow()
		{			
			new Program(this);

			Loaded += new RoutedEventHandler(MainWindow_Loaded);
		}

		void MainWindow_Loaded(object sender, RoutedEventArgs e)
		{
		}

		public int ToWindowX(int x)
		{
			double factor = canvas.ActualWidth / Globals.ScreenWidth;
			int newX = (int)Math.Round((double)x * factor);
			return newX;
		}

		public int ToWindowY(int y)
		{
			double factor = canvas.ActualHeight / Globals.ScreenHeight;
			int newY = (int)Math.Round((double)y * factor);
			return newY;
		}

		/// <summary>
		/// Will be called when a new message was queued and we should do something with the scene
		/// </summary>
		public void MessageQueued(object sender, Events.MessageQueuedArgs args)
		{
			this.Dispatcher.Invoke(
				new Action(delegate()
					{
						// The message
						Message message = args.Message;

						// Active check
						if (message as ActiveIdsMessage != null)
						{
							CheckActiveIds(message as ActiveIdsMessage);
						}
						// Did an avatar move?
						else if (message as AvatarMoveMessage != null)
						{
							AvatarMoved(message as AvatarMoveMessage);
						}
						// Did a thingy move?
						else if (message as ThingyMoveMessage != null)
						{
							ThingyMoved(message as ThingyMoveMessage);
						}
					}
					)
			);
		}

		private void CheckActiveIds(ActiveIdsMessage message)
		{
			foreach (ThingyGraphic tg in ThingyGraphics)
			{
				if (!message.IDs.Contains(tg.ThingyID))
				{
					// Remove from the scene
					canvas.Children.Remove(tg);
					ThingyGraphics.Remove(tg);
					break;
				}
			}

			foreach (AvatarGraphic ag in AvatarGraphics)
			{
				if (!message.IDs.Contains(ag.AvatarID))
				{
					// Remove from the scene
					canvas.Children.Remove(ag);
					AvatarGraphics.Remove(ag);
					break;
				}
			}
		}

		private void AvatarMoved(AvatarMoveMessage message)
		{
			AvatarGraphic graphic;

			// See if there is one already
			var candidates = from ag in AvatarGraphics
							 where ag.IsGraphicFor(message.Avatar)
							 select ag;

			// Found it!
			if (candidates.Count() > 0)
			{
				graphic = candidates.First();
			}
			else
			{
				// Create a new one
				graphic = new AvatarGraphic(this, message.Avatar);
				AvatarGraphics.Add(graphic);
				canvas.Children.Add(graphic);
			}

			graphic.Update();
		}

		private void ThingyMoved(ThingyMoveMessage message)
		{
			ThingyGraphic graphic;

			// See if there is one already
			var candidates = from tg in ThingyGraphics
							 where tg.IsGraphicFor(message.Thingy)
							 select tg;

			// Found it!
			if (candidates.Count() > 0)
			{
				graphic = candidates.First();
			}
			else
			{
				// Create a new one
				graphic = new ThingyGraphic(this, message.Thingy);
				ThingyGraphics.Add(graphic);
				canvas.Children.Add(graphic);
			}

			graphic.Update();
		}
	}
}
